/*
 * Copyright 2010 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.locationbasedagent;

import java.util.ArrayList;
import java.util.List;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.locationbasedagent.shared.HouseListingProxy;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

public class SearchByLocationActivity extends MapActivity implements AsyncTaskDelegate
{    
	MapView mapView; 
    MapController mc;
    GeoPoint p;
    
    AsyncFetchTask task;
	private List<HouseListingProxy> items = new ArrayList<HouseListingProxy>();

	private int min_latitude = 0;
	private int max_latitude = 0;
	private int min_longitude = 0;
	private int max_longitude = 0;
	
	private LocationManager locationManager;
	
	private Drawable myLocationMarker;
	private LBAItemizedOverlay myLocationOverlay;
	private Location currentGPSLocation;
	
	private String radiusChoice;
	private ProgressDialog dialog = null;
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
    	Bundle bundle = getIntent().getExtras();
    	super.onCreate(savedInstanceState);
    	dialog = ProgressDialog.show(this, "Loading...", "Retrieving search results", true);
        setContentView(R.layout.searchbylocation);
        mapView = (MapView) findViewById(R.id.mapView);
        mapView.setBuiltInZoomControls(true);
        
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
				0, new GeoUpdateHandler());
		myLocationMarker = this.getResources().getDrawable(R.drawable.gpsdot); 
		myLocationOverlay = new LBAItemizedOverlay(myLocationMarker, this);
		currentGPSLocation = new Location("");
		currentGPSLocation.setLatitude(0);
		currentGPSLocation.setLongitude(0);
		
        mc = mapView.getController();
        
		String addressValue = bundle.getString("address");
		String cityValue = bundle.getString("city");
		String zipValue = bundle.getString("zip");
		radiusChoice = bundle.getString("radius");
        fetchHouseListings(addressValue, cityValue, zipValue);
        
    }
 
    @Override
    protected boolean isRouteDisplayed() {
        // TODO Auto-generated method stub
        return false;
    }
    
    public class GeoUpdateHandler implements LocationListener {

		@Override
		public void onLocationChanged(Location location) {
		    List<Overlay> listOfOverlays = mapView.getOverlays();
		    listOfOverlays.remove(myLocationOverlay);
			int lat = (int) (location.getLatitude() * 1E6);
			int lng = (int) (location.getLongitude() * 1E6);
			GeoPoint point = new GeoPoint(lat, lng);
			currentGPSLocation.setLatitude(point.getLatitudeE6() / 1E6);
			currentGPSLocation.setLongitude(point.getLongitudeE6() / 1E6);
	      	OverlayItem overlayitem = new OverlayItem(point, "", "");
        	myLocationOverlay.addOverlay(overlayitem);
        	listOfOverlays.add(myLocationOverlay);
  
			//mc.setCenter(point); //	mapController.setCenter(point);
			mapView.invalidate();
		}

		@Override
		public void onProviderDisabled(String provider) {
		}

		@Override
		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	}
    
   
    public class LBAItemizedOverlay extends ItemizedOverlay<OverlayItem> {

    	private ArrayList<OverlayItem> mOverlays;
    	private Context mContext;
    	
    	public LBAItemizedOverlay(Drawable defaultMarker) {
    		super(boundCenterBottom(defaultMarker));
    		mOverlays = new ArrayList<OverlayItem>();
    		populate();
    	}
    	
    	public LBAItemizedOverlay(Drawable defaultMarker, Context context) {
    		super(boundCenterBottom(defaultMarker));
    		mOverlays = new ArrayList<OverlayItem>();
    		mContext = context;
    	}

    	@Override
    	protected OverlayItem createItem(int i) {
    		return mOverlays.get(i);
    	}

    	@Override
    	public int size() {
    		return mOverlays.size();
    	}
    	
    	public void addOverlay(OverlayItem overlay) {
    		mOverlays.add(overlay);
    		populate();
    	}
    	
    	@Override
    	protected boolean onTap(int index) {
    		Intent intent =
                new Intent(SearchByLocationActivity.this,
                        HouseListingActivity.class);
    	    Bundle bundle = new Bundle();
    	    
    	    bundle.putParcelable("listing", new LocalHouseListing(items.get(index)));
    	    intent.putExtras(bundle); 
    	    startActivity(intent);
    		return true;
    	}
    }
    
    
    public void fetchHouseListings(String address, String city, String zip) {
        if (task != null) {
            task.cancel(true);
        }
        task = new AsyncFetchTask(this);
        task.execute("", "", "", address, city, zip,
    			"", "", "", "", "", "", "", 
    			"", "", "", "");
    }

    public void updateHouseListings(List<HouseListingProxy> listings) {
    	dialog.dismiss();
    	this.items.clear();
        if (listings.size() != 0)
        {
        	this.items.addAll(listings);
        	this.createListingOverlays();
        }
    }
    
    public void createListingOverlays()
    {
    	//for each item in the result list, create the Overlay
        List<Overlay> listOfOverlays = mapView.getOverlays();
        Drawable drawable = this.getResources().getDrawable(R.drawable.small_house);
        LBAItemizedOverlay itemizedOverlay;
        
        for (HouseListingProxy house : items)
        {
        	int latitude = (int) (Double.parseDouble(house.getLatitude()) * 1E6);
        	int longitude = (int) (Double.parseDouble(house.getLongitude()) * 1E6);
        	GeoPoint point = new GeoPoint(latitude, longitude);
        	Location houseLocation = new Location("");
        	houseLocation.setLatitude(point.getLatitudeE6() / 1E6);
        	houseLocation.setLongitude(point.getLongitudeE6() / 1E6);
        	
        	float distance = currentGPSLocation.distanceTo(houseLocation);
        	
        	if (Integer.parseInt(radiusChoice) == 0 ||
        			(distance) < (1610*Integer.parseInt(radiusChoice)))
        	{
        	
		    	addPointForZoomCalc((int)(point.getLatitudeE6()), (int)(point.getLongitudeE6()));
		    	
		    	itemizedOverlay = new LBAItemizedOverlay(drawable, this);
		    	OverlayItem overlayitem = new OverlayItem(point, house.getListingName(), house.getListingAddress());
		    	itemizedOverlay.addOverlay(overlayitem);
		    	listOfOverlays.add(itemizedOverlay);
        	}
        }
        
        //check to see if the GPS location should be added to the zoom calculation
	        if (currentGPSLocation.getLatitude() != 0 && Integer.parseInt(radiusChoice) > 0)
	        {
	        	addPointForZoomCalc((int)(currentGPSLocation.getLatitude() * 1E6), (int)(currentGPSLocation.getLongitude() * 1E6));
	        }
        	
        
//        

        mc.zoomToSpan(Math.abs(max_latitude - min_latitude), Math.abs(max_longitude - min_longitude));
        mc.animateTo(new GeoPoint( 
        		(int) (max_latitude + min_latitude)/2, 
        		(int) (max_longitude + min_longitude)/2 ));
        mapView.invalidate();
    }
    
    public void addPointForZoomCalc(int latitude, int longitude)
    {
    	//check the lat/long values against the max/min
    	min_latitude = (min_latitude == 0) ? latitude : Math.min(latitude, min_latitude);
    	max_latitude = (max_latitude == 0) ? latitude : Math.max(latitude, max_latitude);
    	min_longitude = (min_longitude == 0) ? longitude : Math.min(longitude, min_longitude);
    	max_longitude = (max_longitude == 0) ? longitude : Math.max(longitude, max_longitude);
    	
    	return;
    }

    
    
}